using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Dynamic.Core;
using System.Threading.Tasks;
using Acme.BookStore.Domain.Entities;
using Acme.BookStore.EntityFrameworkCore;
using Acme.BookStore.Kehus;
using Microsoft.EntityFrameworkCore;
using Volo.Abp.Domain.Repositories.EntityFrameworkCore;
using Volo.Abp.EntityFrameworkCore;

namespace Acme.BookStore.EntityFrameworkCore.Kehus
{
    public class KehuRepository : EfCoreRepository<BookStoreDbContext, Kehu, string>, IKehuRepository
    {
        public KehuRepository(IDbContextProvider<BookStoreDbContext> dbContextProvider) 
            : base(dbContextProvider)
        {
        }

        public async Task<List<Kehu>> GetListAsync(
            int skipCount,
            int maxResultCount,
            string sorting,
            string filter = null)
        {
            var dbSet = await GetDbSetAsync();
            return await dbSet
                .WhereIf(
                    !filter.IsNullOrWhiteSpace(),
                    kehu => kehu.Name.Contains(filter)
                )
                .OrderBy(sorting)
                .Skip(skipCount)
                .Take(maxResultCount)
                .ToListAsync();
        }

        public async Task<List<Kehu>> GetListAsync(
            int skipCount,
            int maxResultCount,
            string sorting,
            string filter = null,
            string name = null,
            string contactPerson = null,
            string phone = null,
            string mobile = null,
            string enterpriseAttribute = null)
        {
            var dbSet = await GetDbSetAsync();
            return await dbSet
                .WhereIf(
                    !filter.IsNullOrWhiteSpace(),
                    kehu => kehu.Name.Contains(filter) ||
                           kehu.ContactPerson.Contains(filter) ||
                           kehu.Phone.Contains(filter) ||
                           kehu.Mobile.Contains(filter)
                )
                .WhereIf(
                    !name.IsNullOrWhiteSpace(),
                    kehu => kehu.Name.Contains(name)
                )
                .WhereIf(
                    !contactPerson.IsNullOrWhiteSpace(),
                    kehu => kehu.ContactPerson.Contains(contactPerson)
                )
                .WhereIf(
                    !phone.IsNullOrWhiteSpace(),
                    kehu => kehu.Phone.Contains(phone)
                )
                .WhereIf(
                    !mobile.IsNullOrWhiteSpace(),
                    kehu => kehu.Mobile.Contains(mobile)
                )
                .WhereIf(
                    !enterpriseAttribute.IsNullOrWhiteSpace(),
                    kehu => kehu.EnterpriseAttribute.Contains(enterpriseAttribute)
                )
                .OrderBy(sorting)
                .Skip(skipCount)
                .Take(maxResultCount)
                .ToListAsync();
        }
        
        public async Task<List<Kehu>> SearchByNameAsync(
            int skipCount,
            int maxResultCount,
            string sorting,
            string nameKeyword)
        {
            var dbSet = await GetDbSetAsync();
            return await dbSet
                .WhereIf(
                    !nameKeyword.IsNullOrWhiteSpace(),
                    kehu => EF.Functions.ILike(kehu.Name, $"%{nameKeyword}%")
                )
                .OrderBy(sorting)
                .Skip(skipCount)
                .Take(maxResultCount)
                .ToListAsync();
        }

        public async Task<long> GetCountAsync(string filter = null)
        {
            var dbSet = await GetDbSetAsync();
            return await dbSet
                .WhereIf(
                    !filter.IsNullOrWhiteSpace(),
                    kehu => kehu.Name.Contains(filter)
                )
                .LongCountAsync();
        }

        public async Task<long> GetCountAsync(
            string filter = null,
            string name = null,
            string contactPerson = null,
            string phone = null,
            string mobile = null,
            string enterpriseAttribute = null)
        {
            var dbSet = await GetDbSetAsync();
            return await dbSet
                .WhereIf(
                    !filter.IsNullOrWhiteSpace(),
                    kehu => kehu.Name.Contains(filter) ||
                           kehu.ContactPerson.Contains(filter) ||
                           kehu.Phone.Contains(filter) ||
                           kehu.Mobile.Contains(filter)
                )
                .WhereIf(
                    !name.IsNullOrWhiteSpace(),
                    kehu => kehu.Name.Contains(name)
                )
                .WhereIf(
                    !contactPerson.IsNullOrWhiteSpace(),
                    kehu => kehu.ContactPerson.Contains(contactPerson)
                )
                .WhereIf(
                    !phone.IsNullOrWhiteSpace(),
                    kehu => kehu.Phone.Contains(phone)
                )
                .WhereIf(
                    !mobile.IsNullOrWhiteSpace(),
                    kehu => kehu.Mobile.Contains(mobile)
                )
                .WhereIf(
                    !enterpriseAttribute.IsNullOrWhiteSpace(),
                    kehu => kehu.EnterpriseAttribute.Contains(enterpriseAttribute)
                )
                .LongCountAsync();
        }
        
        public async Task<long> GetCountByNameAsync(string nameKeyword)
        {
            var dbSet = await GetDbSetAsync();
            return await dbSet
                .WhereIf(
                    !nameKeyword.IsNullOrWhiteSpace(),
                    kehu => EF.Functions.ILike(kehu.Name, $"%{nameKeyword}%")
                )
                .LongCountAsync();
        }
    }
} 